import * as signalR from '@microsoft/signalr'
import { useRoomStore } from '@/stores/room'
import { useGameStore } from '@/stores/game'

// 连接状态
let isConnected = false
let connection = null
let roomStore = null
let gameStore = null
let cachedGames = null // 新增：游戏列表本地缓存

// 初始化stores
function initializeStores() {
  try {
    roomStore = useRoomStore()
    gameStore = useGameStore()
  } catch (error) {
    console.error('初始化store失败:', error)
  }
}

// 创建连接
async function createConnection() {
  try {
    // 获取Hub URL - 与后端路由配置匹配
    const hubUrl = import.meta.env.VITE_API_URL + '/hubs/game'
    console.log('连接到SignalR Hub:', hubUrl)
    
    // 创建SignalR连接
    connection = new signalR.HubConnectionBuilder()
      .withUrl(hubUrl)
      .withAutomaticReconnect()
      .build()
    
    // 监听连接成功事件
    connection.on('connected', () => {
      console.log('SignalR连接成功')
      isConnected = true
    })
    
    // 监听玩家加入事件
    connection.on('PlayerJoined', (player) => {
      console.log('玩家加入:', player)
      // 这里可以添加玩家加入的视觉反馈
    })
    
    // 监听玩家离开事件
    connection.on('PlayerLeft', (playerId) => {
      console.log('玩家离开:', playerId)
      // 这里可以添加玩家离开的视觉反馈
    })
    
    // 监听游戏更新事件 - 增强版，确保正确处理所有玩家数据
    connection.on('GameUpdated', (gameData) => {
      // 完整打印接收到的游戏数据，用于详细调试
      console.log('===== 游戏更新事件 =====')
      console.log('接收到的完整gameData:', gameData)
      console.log('gameData类型:', typeof gameData)
      console.log('gameData是否包含Players属性:', 'Players' in gameData)
      console.log('gameData是否包含players属性:', 'players' in gameData)
      
      // 增强: 更健壮地处理玩家列表，同时检查Players和players属性
      const playersData = gameData.Players || gameData.players || []
      console.log('接收到的玩家数量:', playersData.length)
      console.log('接收到的玩家列表:', playersData)
      
      // 打印每个玩家的详细信息
      if (playersData.length > 0) {
        console.log('玩家详细信息:')
        playersData.forEach((player, index) => {
          console.log(`玩家${index + 1}:`, {
            id: player.id || player.Id,
            name: player.name || player.Name,
            colorCode: player.ColorCode,
            color: player.color,
            hasId: 'id' in player || 'Id' in player,
            hasName: 'name' in player || 'Name' in player,
            hasColorCode: 'ColorCode' in player,
            hasColor: 'color' in player
          })
        })
      }
      
      // 保存当前玩家的本地颜色设置，防止被后端更新覆盖
      let currentPlayerLocalColor = null;
      const currentPlayerBeforeUpdate = roomStore?.players?.find(p => p.isCurrent);
      if (currentPlayerBeforeUpdate && currentPlayerBeforeUpdate.color) {
        currentPlayerLocalColor = currentPlayerBeforeUpdate.color;
        console.log(`保存当前玩家的本地颜色设置: ${currentPlayerLocalColor}`);
      }

      // 转换玩家数据格式，并确保保留当前玩家的本地颜色设置
      const formattedPlayers = playersData.map(player => {
        const isCurrentPlayer = player.id === (currentPlayerBeforeUpdate?.id || player.Id === currentPlayerBeforeUpdate?.id);
        return {
          id: player.id || player.Id || `player_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
          name: player.name || player.Name || '未知玩家',
          color: isCurrentPlayer && currentPlayerLocalColor ? currentPlayerLocalColor : (player.color || player.ColorCode || '#000'),
          score: player.score || player.Score || 0,
          ready: player.ready || player.Ready || false,
          area: player.area || player.Area || 0,
          isCurrent: isCurrentPlayer
        };
      });

      console.log('格式化后的玩家数据:');
      formattedPlayers.forEach(player => {
        console.log(`${player.name} (${player.id}): 颜色=${player.color}, 准备状态=${player.ready}, 是否当前玩家=${player.isCurrent}`);
      });
      
      console.log('转换后的玩家列表（包含颜色）:', formattedPlayers.map(p => ({name: p.name, color: p.color})))
      
      console.log('转换后的玩家列表:', formattedPlayers)
      
      // 更新玩家列表 - 标记当前玩家的逻辑已移至room.js的setPlayers方法中
      roomStore.setPlayers(formattedPlayers)
      
      // 同步当前玩家颜色到游戏状态
      setTimeout(() => {
        const currentPlayer = roomStore.players.find(p => p.isCurrent)
        if (currentPlayer) {
          // 优先使用roomStore中已存在的当前玩家颜色，然后才是本地保存的颜色
          const colorToUse = currentPlayer.color || currentPlayerLocalColor || '#000';
          console.log(`同步当前玩家颜色到游戏状态: ${colorToUse}`)
          
          // 确保roomStore中的颜色与我们要使用的颜色一致
          if (currentPlayer.color !== colorToUse) {
            currentPlayer.color = colorToUse;
            console.log(`已更新roomStore中当前玩家的颜色: ${colorToUse}`);
          }
          
          // 同步到gameStore，确保游戏状态中的颜色也是最新的
          gameStore.setPlayerColor(colorToUse);
        } else {
          console.warn('未找到当前玩家或玩家颜色未设置')
        }
      }, 100) // 延迟执行，确保玩家标记完成后再同步颜色
      
      // 更新游戏状态，同时检查status和Status属性，并映射后端状态到前端状态
      const backendStatus = gameData.status || gameData.Status || 'Created'
      let frontendStatus = 'waiting'
      
      // 映射后端状态到前端状态
      switch (backendStatus) {
        case 'Created':
          frontendStatus = 'waiting'
          break
        case 'InProgress':
          frontendStatus = 'playing'
          break
        case 'Completed':
          frontendStatus = 'finished'
          break
        default:
          frontendStatus = backendStatus.toLowerCase()
      }
      
      console.log(`游戏状态映射: 后端(${backendStatus}) -> 前端(${frontendStatus})`)
      roomStore.setStatus(frontendStatus)
    })
    
    // 监听游戏开始事件
    connection.on('GameStarted', (gameData) => {
      console.log('游戏开始:', gameData)
      roomStore.setStatus('playing')
      
      // 同步当前玩家颜色
      const currentPlayer = roomStore.players.find(p => p.isCurrent)
      if (currentPlayer && currentPlayer.color) {
        console.log(`游戏开始时同步玩家颜色: ${currentPlayer.color}`)
        gameStore.setPlayerColor(currentPlayer.color)
      }
      
      gameStore.startGameTimer()
    })
    
    // 监听涂色操作事件 - 现在使用后端传来的玩家颜色
    connection.on('PaintActionPerformed', (data) => {
      // 增强的调试日志
      console.log('===== 收到涂色操作事件 =====')
      console.log('事件数据完整内容:', JSON.stringify(data, null, 2))
      console.log('事件数据类型:', typeof data)
      console.log('事件数据包含的属性:', Object.keys(data))
      
      // 保存涂色事件到localStorage，用于调试
      try {
        const receivedPaintActions = JSON.parse(localStorage.getItem('receivedPaintActions') || '[]');
        const actionData = {
          timestamp: new Date().toISOString(),
          sender: { playerId: data.PlayerId, playerName: data.PlayerName },
          position: { X: data.X, Y: data.Y },
          color: data.Color,
          gameId: data.GameId
        };
        receivedPaintActions.push(actionData);
        localStorage.setItem('receivedPaintActions', JSON.stringify(receivedPaintActions.slice(-100)));
      } catch (e) {
        console.warn('无法保存收到的涂色操作到localStorage:', e);
      }
      
      // 检查是否已初始化房间存储
      if (!roomStore) {
        console.warn('房间存储未初始化，跳过涂色操作处理');
        return;
      }
      
      // 如果当前没有加入任何游戏，跳过处理
      if (!roomStore.roomId) {
        console.warn('当前未加入任何游戏，跳过涂色操作处理');
        return;
      }
      
      // 过滤不属于当前游戏的涂色操作
      // 注意：data.GameId可能是GUID对象或字符串，需要转换为字符串进行比较
      const eventGameId = data.GameId?.toString() || '';
      const currentRoomId = roomStore.roomId?.toString() || '';
      
      if (eventGameId && currentRoomId && eventGameId !== currentRoomId) {
        console.log(`过滤掉不属于当前游戏的涂色操作: 事件GameId=${eventGameId}, 当前RoomId=${currentRoomId}`);
        return;
      }
      
      // 检查是否是当前玩家自己的涂色操作，如果是则跳过（避免重复绘制）
      // 使用更宽松的检查方式，同时检查tempPlayerId和currentPlayerId
      const currentPlayer = roomStore.players.find(p => p.isCurrent);
      const tempPlayerId = roomStore.tempPlayerId;
      const currentPlayerId = roomStore.currentPlayerId;
      
      if ((currentPlayer && data.PlayerId === currentPlayer.id) ||
          (tempPlayerId && data.PlayerId === tempPlayerId) ||
          (currentPlayerId && data.PlayerId === currentPlayerId)) {
        console.log('跳过当前玩家自己的涂色操作，避免重复绘制', {
          currentPlayerId: currentPlayer?.id,
          tempPlayerId,
          currentPlayerId,
          eventPlayerId: data.PlayerId
        });
        return;
      }
      
      // 保存当前颜色以便恢复
      const originalColor = gameStore.myColor;
      
      // 使用操作发送者的颜色
      if (data.Color) {
        console.log(`使用发送者的颜色: ${data.Color} (原颜色: ${originalColor})`);
        gameStore.myColor = data.Color;
      } else {
        console.warn('涂色事件中没有颜色信息，使用默认颜色');
        gameStore.myColor = '#000000';
      }
      
      // 确保颜色已设置
      console.log(`当前使用的颜色: ${gameStore.myColor}`)
      
      // 获取当前画布的引用
      const canvas = gameStore.canvas;
      console.log('画布引用状态:', { canvas: !!canvas, width: canvas?.width, height: canvas?.height });
      
      if (canvas) {
        // 定义网格大小常量（应与后端和GameCanvas组件保持一致）
        const GRID_SIZE = 10;
        
        // 计算画布大小
        const canvasWidth = canvas.width;
        const canvasHeight = canvas.height;
        
        // 将网格坐标转换为像素坐标
        // 计算每个格子的大小
        const cellWidth = canvasWidth / GRID_SIZE;
        const cellHeight = canvasHeight / GRID_SIZE;
        
        // 计算格子中心的像素坐标
        const pixelX = Math.floor(data.X * cellWidth);
        const pixelY = Math.floor(data.Y * cellHeight);
        
        // 调整绘制位置，考虑画笔大小，确保绘制在格子中心
        const adjustedPixelX = pixelX - gameStore.brushSize / 2;
        const adjustedPixelY = pixelY - gameStore.brushSize / 2;
        
        console.log('收到涂色操作 - 网格坐标:', {X: data.X, Y: data.Y}, '转换为像素坐标:', {pixelX, pixelY}, 
                    '调整后坐标:', {adjustedPixelX, adjustedPixelY}, '格子大小:', {cellWidth, cellHeight}, '画布大小:', {canvasWidth, canvasHeight})
        
        // 使用临时颜色绘制其他玩家的涂色
        console.log(`绘制其他玩家涂色: 位置(${adjustedPixelX},${adjustedPixelY}), 颜色: ${gameStore.myColor}`)
        gameStore.drawPixel(adjustedPixelX, adjustedPixelY)
      } else {
        // 如果画布还未初始化，使用原始坐标（作为后备方案）
        console.warn('画布未初始化，使用原始坐标作为后备方案:', {X: data.X, Y: data.Y});
        // 调整绘制位置，考虑画笔大小
        const adjustedX = data.X - gameStore.brushSize / 2;
        const adjustedY = data.Y - gameStore.brushSize / 2;
        console.log(`绘制其他玩家涂色(后备): 位置(${adjustedX},${adjustedY}), 颜色: ${gameStore.myColor}`)
        gameStore.drawPixel(adjustedX, adjustedY)
      }
      
      // 立即恢复当前玩家的颜色 - 同时更新roomStore和gameStore
      console.log(`立即恢复当前玩家的颜色: ${originalColor}`);
      
      // 1. 重新获取最新的当前玩家引用，不依赖之前定义的可能过时的currentPlayer变量
      const latestCurrentPlayer = roomStore.players.find(p => p.isCurrent);
      
      if (latestCurrentPlayer) {
        // 更新roomStore中当前玩家的颜色
        latestCurrentPlayer.color = originalColor;
        console.log(`已更新roomStore中当前玩家的颜色: ${originalColor}`);
      } else {
        console.warn('未找到当前玩家，无法更新roomStore中的颜色');
      }
      
      // 2. 再更新gameStore的颜色
      gameStore.myColor = originalColor;
      
      // 确保颜色恢复成功
      console.log(`恢复后的游戏存储颜色: ${gameStore.myColor}`)
      
      // 再次验证颜色是否正确恢复
      if (latestCurrentPlayer && latestCurrentPlayer.color !== gameStore.myColor) {
        console.warn('颜色同步不一致:', {
          roomStoreColor: latestCurrentPlayer.color,
          gameStoreColor: gameStore.myColor
        });
        // 强制同步
        latestCurrentPlayer.color = gameStore.myColor;
      }
      
      // 更新面积统计
      gameStore.updateAreas()
      
      // 记录涂色操作完成
      console.log('涂色操作处理完成')
      
      // 记录当前游戏状态
      if (roomStore && gameStore) {
        console.log('当前游戏状态:', {
          gameStatus: roomStore.gameStatus,
          currentPlayer: roomStore.players.find(p => p.isCurrent)?.id,
          playerCount: roomStore.players.length,
          currentColor: gameStore.myColor
        });
      }
    })
    
    // 监听游戏创建成功事件
    connection.on('GameCreated', (gameId) => {
      console.log('游戏创建成功:', gameId)
    })
    
    // 监听计时器事件
    connection.on('Timer', (t) => {
      gameStore.setTimeLeft(t)
    })
    
    // 监听批量绘制事件
    connection.on('PaintBatch', (actions) => {
      actions.forEach(({ x, y, color }) => {
        gameStore.myColor = color
        gameStore.drawPixel(x, y)
      })
      gameStore.updateAreas()
    })
    
    // 监听连接关闭事件
    connection.onclose((error) => {
      console.log('SignalR连接已关闭', error)
      isConnected = false
      // 尝试重连
      setTimeout(() => {
        if (!isConnected) {
          console.log('尝试重新连接...')
          createConnection()
        }
      }, 5000)
    })
    
    // 监听重连成功事件
    connection.onreconnected((connectionId) => {
      console.log('SignalR重新连接成功', connectionId)
      isConnected = true
    })
    
    // 启动连接
    try {
      await connection.start()
      console.log('SignalR连接已启动')
      isConnected = true
    } catch (startError) {
      console.error('启动连接时出错:', startError)
      isConnected = false
      throw startError
    }
  } catch (error) {
    console.error('创建连接时出错:', error)
    isConnected = false
    throw error
  }
}

// 初始化连接函数 - 不再在模块顶层直接调用异步函数
function initializeConnection() {
  // 初始化store引用
  initializeStores()
  createConnection().catch(err => {
    console.error('初始连接失败，但应用程序继续运行:', err);
  });
}

// 导出服务
export const socketService = {
  // 添加初始化连接的方法
  initialize: initializeConnection,
  // 获取连接状态
  get isConnected() {
    return isConnected
  },
  // 创建房间方法 - 注意后端方法名是CreateGame
  async createRoom(name, customId = null) {
    try {
      if (!connection || !isConnected) {
        await createConnection()
      }
      
      // 调用后端CreateGame方法，默认gridSize=10, maxPlayers=4
      const gridSize = 10;
      const maxPlayers = 4;
      const gameId = await connection.invoke('CreateGame', name, gridSize, maxPlayers, customId)
      return { room: { id: gameId } }
    } catch (error) {
      console.error('创建房间失败:', error)
      throw error
    }
  },
  
  // 加入房间方法 - 注意后端方法名是JoinGame
  async joinRoom(roomId) {
    try {
      if (!connection || !isConnected) {
        await createConnection()
      }
      
      console.log('准备加入房间:', roomId)
      
      // 调用后端JoinGame方法，需要roomId和playerName两个参数
      // 增强: 生成一个更有可能唯一的玩家名称
      const playerName = roomStore?.currentPlayer?.name || `Player_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`;
      console.log('使用玩家名称:', playerName)
      
      const playerId = await connection.invoke('JoinGame', roomId, playerName)
      console.log('成功加入房间，返回的playerId:', playerId)
      
      // 主动请求游戏更新，确保获取最新的玩家列表
      setTimeout(async () => {
        try {
          console.log('主动请求游戏更新以获取完整玩家列表')
          await connection.invoke('GetActiveGames') // 此调用会触发后端更新游戏状态
        } catch (error) {
          console.log('主动请求游戏更新失败:', error)
        }
      }, 500)
      
      return { playerId }
    } catch (error) {
      console.error('加入房间失败:', error)
      throw error
    }
  },
  
  // 离开房间方法 - 注意后端方法名是LeaveGame
  async leaveRoom(roomId, playerId) {
    try {
      if (connection && isConnected) {
        await connection.invoke('LeaveGame', roomId, playerId)
      }
    } catch (error) {
      console.error('离开房间失败:', error)
      throw error
    }
  },
  
  // 发送涂色操作 - 注意后端方法名是PerformPaintAction
  async emitPaint(roomId, playerId, x, y) {
    try {
      if (!connection || !isConnected) {
        console.warn('WebSocket连接未建立，无法发送涂色操作');
        return;
      }

      // 增强版：详细记录接收到的参数信息
      console.log('准备发送涂色操作，原始参数:', {
        roomId: { value: roomId, type: typeof roomId, length: String(roomId).length },
        playerId: { value: playerId, type: typeof playerId, length: String(playerId).length },
        x: { value: x, type: typeof x },
        y: { value: y, type: typeof y }
      });

      // 确保x和y是整数
      const gridX = parseInt(x);
      const gridY = parseInt(y);
      if (isNaN(gridX) || isNaN(gridY)) {
        console.error('坐标值无效:', {x, y});
        throw new Error('坐标值必须是有效的数字');
      }

      // 验证坐标是否为非负数（负数坐标无效）
      if (gridX < 0 || gridY < 0) {
        console.error('坐标值不能为负数:', {x: gridX, y: gridY});
        throw new Error('坐标值不能为负数');
      }

      // 注意：最大坐标范围验证由后端处理，这样可以确保前后端网格大小保持一致
      // 前端不再硬编码网格大小，避免与实际游戏设置不匹配的问题

      // 验证roomId和playerId是否为有效的GUID格式
      const gameIdStr = String(roomId).trim(); // 注意：后端参数名是gameId
      const playerIdStr = String(playerId).trim();

      // 增强的GUID验证和日志记录
      console.log(`验证游戏ID格式: ${gameIdStr}, GUID格式: ${this.isValidGuid(gameIdStr)}`);
      console.log(`验证玩家ID格式: ${playerIdStr}, GUID格式: ${this.isValidGuid(playerIdStr)}`);

      // 最终确认要发送的参数
      console.log('实际发送的参数 - 增强版:', {
        gameId: { value: gameIdStr, type: typeof gameIdStr, length: gameIdStr.length },
        playerId: { value: playerIdStr, type: typeof playerIdStr, length: playerIdStr.length },
        x: { value: gridX, type: typeof gridX },
        y: { value: gridY, type: typeof gridY }
      });

      // 保存涂色操作信息到localStorage，用于调试
      const paintActionInfo = {
        timestamp: new Date().toISOString(),
        gameId: gameIdStr,
        playerId: playerIdStr,
        x: gridX,
        y: gridY,
        connectionId: connection?.connectionId
      };
      console.log('涂色操作详情:', paintActionInfo);
      
      // 记录到localStorage便于调试
      try {
        const paintHistory = JSON.parse(localStorage.getItem('paintHistory') || '[]');
        paintHistory.push(paintActionInfo);
        localStorage.setItem('paintHistory', JSON.stringify(paintHistory.slice(-100))); // 只保留最近100条记录
      } catch (e) {
        console.warn('无法保存涂色历史到localStorage:', e);
      }

      // 验证connection和invoke方法存在性
      console.log('SignalR连接状态验证:', { connection: !!connection, isConnected: isConnected, hasInvoke: typeof connection?.invoke === 'function' });

      try {
        // 调用后端方法 - 确保参数顺序和类型正确，注意后端参数名是gameId
        console.log('准备调用后端PerformPaintAction方法...');
        
        // 特别注意：后端方法签名是PerformPaintAction(gameId, playerId, x, y)
        // 确保参数顺序和类型完全匹配
        const invokeResult = await connection.invoke('PerformPaintAction', gameIdStr, playerIdStr, gridX, gridY);
        console.log('涂色操作发送成功，后端返回结果:', invokeResult);
      } catch (invokeError) {
        console.error('调用后端PerformPaintAction方法失败:', invokeError);
        console.error('错误类型:', invokeError.name);
        console.error('错误消息:', invokeError.message);
        console.error('错误堆栈:', invokeError.stack);
        
        // 尝试重新建立连接并再次调用（如果是连接问题）
        if (invokeError.message.includes('disconnected') || invokeError.message.includes('closed')) {
          console.log('检测到连接问题，尝试重新连接...');
          try {
            await createConnection();
            if (connection && isConnected) {
              console.log('重新连接成功，再次尝试发送涂色操作');
              await connection.invoke('PerformPaintAction', gameIdStr, playerIdStr, gridX, gridY);
              console.log('重新连接后涂色操作发送成功');
            }
          } catch (reconnectError) {
            console.error('重新连接后仍然失败:', reconnectError);
            throw new Error(`重连后仍失败: ${reconnectError.message}`);
          }
        } else {
          throw new Error(`调用后端失败: ${invokeError.message}`);
        }
      }
    } catch (error) {
      console.error('发送涂色操作整体失败:', error);
      // 不抛出错误，避免影响用户体验，让前端继续运行
    }
  },
  
  // 验证GUID格式的辅助方法
  isValidGuid(id) {
    if (!id) return false;
    const guidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
    return guidRegex.test(String(id));
  },
  
  // 设置玩家准备状态 - 参数名与后端保持一致
  async setPlayerReady(gameId, playerId, ready) {
    try {
      if (connection && isConnected) {
        await connection.invoke('SetPlayerReady', gameId, playerId, ready)
      }
    } catch (error) {
      console.error('设置准备状态失败:', error)
      throw error
    }
  },
  
  // 设置玩家颜色 - 新增方法，用于将玩家选择的颜色发送到后端
  async setPlayerColor(roomId, playerId, color) {
    try {
      if (!connection || !isConnected) {
        console.warn('WebSocket连接未建立，无法发送颜色设置');
        return;
      }
      
      console.log(`准备发送玩家颜色设置: 房间ID=${roomId}, 玩家ID=${playerId}, 颜色=${color}`);
      
      // 调用后端SetPlayerColor方法
      await connection.invoke('SetPlayerColor', roomId, playerId, color)
      console.log('玩家颜色设置成功发送到后端');
    } catch (error) {
      console.error('发送玩家颜色设置失败:', error);
      // 不抛出错误，避免影响用户体验，让前端继续运行
    }
  },
  
  // 开始游戏 - 确保参数格式正确
  async startGame(gameId, playerId) {
    try {
      // 额外的防御性检查：确保至少有2名玩家
      if (roomStore && roomStore.players.length < 2) {
        const errorMsg = '至少需要2名玩家才能开始游戏'
        console.warn(errorMsg)
        throw new Error(errorMsg)
      }
      
      // 验证参数格式
      if (!gameId || !playerId) {
        throw new Error('游戏ID和玩家ID不能为空')
      }
      
      // 验证GUID格式
      const guidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
      const gameIdStr = String(gameId).trim();
      const playerIdStr = String(playerId).trim();
      
      console.log('验证GUID前的ID字符串:', {gameIdStr, playerIdStr});
      
      if (!guidRegex.test(gameIdStr) || !guidRegex.test(playerIdStr)) {
        throw new Error('游戏ID或玩家ID格式不正确，请确保是有效的GUID格式')
      }
      
      console.log('GUID验证通过，ID格式正确');
      
      // 在调用StartGame前主动获取后端实际的游戏信息
      console.log('在开始游戏前主动获取后端实际的游戏信息验证玩家数量')
      console.log('尝试验证的gameId:', gameId, '类型:', typeof gameId)
      
      // 禁用缓存，确保获取最新的游戏数据
      let games = null
      try {
        games = await this.getActiveGames(false)
        console.log('获取到的游戏数量:', games?.length || 0)
      } catch (error) {
        console.warn('获取游戏列表出错，将尝试继续执行:', error)
        // 即使获取游戏列表失败，也尝试继续执行
      }
      
      // 后端玩家数量验证 - 采用更宽松的策略
      let backendPlayerCount = -1
      let playerCountValid = true
      
      if (games && Array.isArray(games)) {
        let currentGame = null
        const gameIdStr = String(gameId)
        
        // 增强的游戏查找逻辑，尝试多种匹配方式
        console.log('尝试多种方式查找游戏...')
        
        // 1. 精确匹配id（考虑大小写和类型）
        currentGame = games.find(game => String(game.id) === gameIdStr)
        if (currentGame) {
          console.log('方式1：通过精确ID匹配找到游戏')
        }
        
        // 2. 如果精确匹配失败，尝试通过name属性匹配（针对自定义房间ID）
        if (!currentGame) {
          currentGame = games.find(game => game.name === gameIdStr || game.Name === gameIdStr)
          if (currentGame) {
            console.log('方式2：通过name属性匹配找到游戏')
          }
        }
        
        // 3. 如果仍未找到，尝试部分包含匹配
        if (!currentGame) {
          currentGame = games.find(game => String(game.id).includes(gameIdStr) || gameIdStr.includes(String(game.id)))
          if (currentGame) {
            console.log('方式3：通过部分包含匹配找到游戏')
          }
        }
        
        // 4. 如果所有匹配都失败，记录所有游戏ID用于调试
        if (!currentGame) {
          console.warn('未找到对应游戏，所有游戏ID列表：', games.map(game => game.id))
          // 找不到游戏时，跳过玩家数量验证
          playerCountValid = true
        } else {
          // 更健壮地获取后端玩家数量和状态
          const hasPlayersProperty = 'Players' in currentGame || 'players' in currentGame
          const playersArray = currentGame.Players || currentGame.players
          
          // 同时检查CurrentPlayers字段（从后端返回的ActiveGameDto中）
          const hasCurrentPlayersProperty = 'CurrentPlayers' in currentGame
          const currentPlayersCount = currentGame.CurrentPlayers
          
          // 只有当明确存在players属性且长度为0时，才认为玩家数量不足
          if (hasPlayersProperty && Array.isArray(playersArray) && playersArray.length === 0) {
            backendPlayerCount = 0
            playerCountValid = false
          } else {
            // 对于players属性不存在或不是数组的情况，使用CurrentPlayers字段或不阻止游戏开始
            backendPlayerCount = playersArray?.length || currentPlayersCount || -1
            playerCountValid = true
          }
          
          console.log('后端玩家状态:', {
            hasPlayersProperty,
            playersArrayType: Array.isArray(playersArray) ? 'array' : typeof playersArray,
            hasCurrentPlayersProperty,
            currentPlayersCount,
            estimatedPlayerCount: backendPlayerCount === -1 ? 'unknown' : backendPlayerCount
          })
          console.log('找到的游戏详情:', {id: currentGame.id, name: currentGame.name, players: playersArray, CurrentPlayers: currentPlayersCount})
        }
      } else {
        // 如果获取游戏列表失败或不是数组，跳过玩家数量验证
        console.warn('游戏列表数据异常，将跳过玩家数量验证')
        playerCountValid = true
      }
      
      // 只有当明确知道后端玩家数量为0时，才阻止游戏开始
      if (!playerCountValid) {
        throw new Error(`后端玩家数量不足，当前只有${backendPlayerCount}名玩家，至少需要2名玩家才能开始游戏`)
      } else if (backendPlayerCount >= 0) {
        console.log(`后端玩家数量检查通过：${backendPlayerCount}名玩家`)
      } else {
        console.log('无法确定后端精确玩家数量，将尝试开始游戏')
      }
      
      // 确认连接状态
      console.log('WebSocket连接状态检查:', {isConnected, connectionExists: !!connection})
      
      // 先尝试获取当前玩家信息，确保玩家有效
      try {
        // 这里可以添加获取玩家信息的逻辑，验证玩家有效性
        console.log('尝试验证玩家有效性:', {playerId: playerIdStr})
        // 虽然没有显式的API来获取玩家信息，但我们可以通过检查是否在游戏中等方式验证
        // 例如，检查当前玩家是否在游戏列表中
      } catch (playerVerifyError) {
        console.warn('玩家有效性验证失败，但将继续尝试:', playerVerifyError)
      }
      
      if (connection && isConnected) {
        console.log('准备调用服务器StartGame方法', {gameId: gameIdStr, playerId: playerIdStr})
        
        try {
          // 调用前先验证游戏信息和玩家数量
          console.log('调用前验证游戏信息和玩家数量')
          const gameDetails = await this.getActiveGames(false)
          const targetGame = gameDetails?.find(game => 
            game.Id === gameIdStr || 
            game.Name?.includes(gameIdStr) || 
            gameIdStr.includes(game.Id)
          )
          
          if (targetGame) {
            console.log('找到目标游戏，详细信息:', {
              id: targetGame.Id,
              name: targetGame.Name,
              currentPlayers: targetGame.CurrentPlayers,
              maxPlayers: targetGame.MaxPlayers,
              status: targetGame.Status
            })
            
            // 检查后端玩家数量是否足够
            const backendPlayerCount = targetGame.CurrentPlayers || 0
            console.log('后端报告的玩家数量:', backendPlayerCount)
            
            if (backendPlayerCount < 2) {
              console.warn('后端玩家数量不足2人，但前端认为可以开始游戏')
              // 抛出特定错误，让前端知道问题所在
              throw new Error(`后端玩家数量不足: 只有${backendPlayerCount}名玩家，至少需要2名玩家才能开始游戏。请等待更多玩家加入。`)
            }
          } else {
            console.warn('未找到目标游戏，将尝试直接调用StartGame')
          }
          
          // 确保以字符串形式传递Guid
          await connection.invoke('StartGame', gameIdStr, playerIdStr)
          console.log('服务器StartGame方法调用成功')
        } catch (serverError) {
          console.error('服务器StartGame方法调用失败，错误类型:', serverError.name)
          console.error('服务器StartGame方法调用失败，错误信息:', serverError.message)
          console.error('服务器StartGame方法调用失败，完整错误:', serverError)
          
          // 打印详细的调用参数，确保没有格式问题
          console.log('StartGame调用参数详细信息:', {
            gameId: { value: gameIdStr, type: typeof gameIdStr, length: gameIdStr.length },
            playerId: { value: playerIdStr, type: typeof playerIdStr, length: playerIdStr.length }
          })
          
          // 尝试重新建立连接并再次调用
          try {
            console.log('尝试重新建立连接后再次调用StartGame')
            await createConnection()
            await connection.invoke('StartGame', gameIdStr, playerIdStr)
            console.log('重新连接后StartGame方法调用成功')
          } catch (retryError) {
            console.error('重新连接后StartGame方法仍然调用失败:', retryError)
            
            // 尝试一个备用方案：先获取游戏，然后再次尝试开始
            try {
              console.log('尝试备用方案：先获取游戏信息，然后再次尝试开始')
              const gameDetails = await this.getActiveGames(false)
              console.log('获取游戏详情成功，游戏数量:', gameDetails?.length || 0)
              
              // 再次检查目标游戏信息
              const targetGame = gameDetails?.find(game => 
                game.Id === gameIdStr || 
                game.Name?.includes(gameIdStr) || 
                gameIdStr.includes(game.Id)
              )
              
              if (targetGame) {
                console.log('备用方案中找到目标游戏，玩家数量:', targetGame.CurrentPlayers)
              }
              
              await connection.invoke('StartGame', gameIdStr, playerIdStr)
              console.log('备用方案调用StartGame成功')
            } catch (altError) {
              console.error('备用方案也失败:', altError)
              
              // 尝试使用备用方法（直接调用，绕过部分验证）
              console.log('尝试使用备用方法startGameDirect')
              const directResult = await this.startGameDirect(gameIdStr, playerIdStr)
              if (directResult) {
                console.log('备用方法调用成功')
                return
              }
              
              // 提供更友好的错误信息
              throw new Error(`开始游戏失败：${serverError.message || '服务器返回错误'}。游戏ID: ${gameIdStr.substring(0, 8)}..., 玩家ID: ${playerIdStr.substring(0, 8)}...`)
            }
          }
        }
      } else {

        console.warn('WebSocket连接未建立，无法调用StartGame方法')
        // 尝试重新建立连接
        try {
          console.log('尝试重新建立连接')
          await createConnection()
          if (connection && isConnected) {
            console.log('连接重建成功，现在调用StartGame方法')
            await connection.invoke('StartGame', gameIdStr, playerIdStr)
            console.log('连接重建后StartGame方法调用成功')
          } else {
            console.error('连接重建后仍然未连接')
            throw new Error('WebSocket连接建立失败')
          }
        } catch (connectError) {
          console.error('连接重建失败，无法调用StartGame方法:', connectError)
          throw new Error(`WebSocket连接问题: ${connectError.message}`)
        }
      }
    } catch (error) {
      console.error('开始游戏失败:', error)
      throw error
    }
  },
  
  // 获取活跃游戏列表 - 后端返回List<ActiveGameDto>
  async getActiveGames(useCache = true) {
    try {
      // 如果指定使用缓存且缓存存在，则返回缓存的游戏列表
      if (useCache && cachedGames) {
        console.log('使用缓存的游戏列表')
        return cachedGames
      }
      
      if (!connection || !isConnected) {
        await createConnection()
      }
      
      const games = await connection.invoke('GetActiveGames')
      // 更新缓存
      cachedGames = games
      console.log('获取并缓存新的游戏列表，游戏数量:', games?.length || 0)
      return games
    } catch (error) {
      console.error('获取活跃游戏失败:', error)
      throw error
    }
  },
  
  // 清除游戏列表缓存
  clearGamesCache() {
    console.log('清除游戏列表缓存')
    cachedGames = null
  },
  
  // 验证玩家是否在指定游戏中（用于调试）
  async validatePlayerInGame(gameId, playerId) {
    try {
      console.log('验证玩家是否在游戏中:', {gameId, playerId})
      
      // 获取最新游戏列表
      const games = await this.getActiveGames(false)
      console.log('获取到的游戏数量:', games?.length || 0)
      
      // 查找指定游戏
      const game = games.find(g => String(g.id) === String(gameId))
      
      if (!game) {
        console.warn('未找到指定游戏')
        return { isValid: false, reason: '未找到指定游戏' }
      }
      
      console.log('找到游戏:', {id: game.id, name: game.name, CurrentPlayers: game.CurrentPlayers})
      
      // 由于ActiveGameDto不包含玩家详细信息，我们只能检查游戏是否存在和当前玩家数量
      return {
        isValid: true,
        gameFound: true,
        currentPlayers: game.CurrentPlayers,
        maxPlayers: game.MaxPlayers
      }
    } catch (error) {
      console.error('验证玩家游戏关系失败:', error)
      return { isValid: false, reason: error.message }
    }
  },
  
  // 尝试直接调用StartGame的备用方法，绕过某些验证逻辑（用于调试）
  async startGameDirect(gameId, playerId) {
    try {
      console.log('=== 调用备用StartGame方法 ===')
      console.log('参数:', {gameId: String(gameId), playerId: String(playerId)})
      
      // 直接调用，不进行额外验证
      if (connection && isConnected) {
        console.log('直接调用服务器StartGame方法')
        await connection.invoke('StartGame', String(gameId), String(playerId))
        console.log('备用方法调用StartGame成功')
        return true
      } else {
        console.error('WebSocket未连接，无法调用StartGame')
        return false
      }
    } catch (error) {
      console.error('备用方法调用StartGame失败:', error)
      return false
    }
  }
}